package sharewithus.content.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import net.rubyeye.xmemcached.GetsResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import sharewithus.business.dto.RelationShipMsg;
import sharewithus.content.dao.IFeedCache;
import sharewithus.content.dao.IFeedDao;
import sharewithus.content.dao.IFeedRelationshipCache;
import sharewithus.content.dao.IFeedRelationshipDao;
import sharewithus.content.dto.Feed;
import sharewithus.content.dto.FeedEx;
import sharewithus.content.dto.FeedRelationship;
import sharewithus.content.service.IContentService;

public class ContentServiceImpl implements IContentService{


	@Autowired
	private IFeedDao feedDao;
	
	@Autowired
	private IFeedCache feedCache;
	
	@Qualifier("feedRelationshipDao")
	@Autowired
	private IFeedRelationshipDao frDao;
	
	@Qualifier("feedRelationshipCache")
	@Autowired
	private IFeedRelationshipCache frCache;
	
	public void saveFeed(Feed feed){
		if(feed.getFeedId()==null ||"".equals(feed.getFeedId())){
			feed.setFeedId(UUID.randomUUID().toString());
		}
		
		//save feed to db
		feedDao.saveFeed(feed);
		
		//save feed to memcached
		feedCache.saveFeed(feed);
		
	}

	public void pushFeeds2Subscribers(Feed feed,
			List<RelationShipMsg> followRelationships) {
		
		Iterator<RelationShipMsg>  iter1 = followRelationships.iterator();
		RelationShipMsg rsm = null;
		//save to redis cache
		while(iter1.hasNext()){
			rsm = iter1.next();
			String subScriberId = rsm.getFollower();
			frCache.saveSubscriberFeeds(subScriberId, feed);
		}
		
		//save to db
		Iterator<RelationShipMsg>  iter2 = followRelationships.iterator();
		while(iter1.hasNext()){
			rsm = iter1.next();
			String subScriberId = rsm.getFollower();
			frDao.saveSubscriberFeeds(subScriberId, feed);
		}
	}
	
	public void pushUserFeed(Feed feed){
		//save feed to db
		
		//save feed to memcached
		frCache.pushUserFeedRelationship(feed);
	}

	public void pullFeeds(List<Feed> feeds, RelationShipMsg newFollowMsg) {
		Iterator<Feed>  iter1 = feeds.iterator();
		Feed feed = null;
		while(iter1.hasNext()){
			feed = iter1.next();
			frDao.saveSubscriberFeeds(newFollowMsg.getFollower(), feed);
		}
		
		Iterator<Feed>  iter2 = feeds.iterator();
		while(iter1.hasNext()){
			feed = iter1.next();
			frCache.saveSubscriberFeeds(newFollowMsg.getFollower(), feed);
		}
		
	}
	
	public List<Feed> getSubscribedFeeds(String subscriberId,
			int pageSize, int pageNumber) {
		List<FeedRelationship> frs = null;
		
		frs  = frCache.getSubscribedFeeds(subscriberId, pageSize, pageNumber);
		
		return generateFeeds(frs);
	}

	public List<Feed> getSubscribedFeeds(String subscriberId) {
		// TODO Auto-generated method stub
		return getSubscribedFeeds(subscriberId, -1, -1);
	}
	
	
	public List<Feed> getUserFeeds(String ownerId){
		
		return getUserFeeds(ownerId, -1, -1);
	}
	
	public List<Feed> getUserFeeds(String ownerId, int pageSize, int pageNum){
		List<String> feedIds = null;
		
		feedIds  = frCache.getUserFeedPageIds(ownerId, pageSize, pageNum);
		return getFeedbyIds(feedIds);
	}

	private List<Feed> generateFeeds(List<FeedRelationship> frs) {
		
		List<String> feedIds = new ArrayList<String>();
		Iterator<FeedRelationship> iter = frs.iterator();
		FeedRelationship fr = null;
		while(iter.hasNext()){
			fr = iter.next();
			feedIds.add(fr.getFeedId());
		}
		return getFeedbyIds(feedIds);
	}

	private List<Feed> getFeedbyIds( List<String> feedIds) {
		Map<String, GetsResponse<Feed>> cacheFeedsRes = feedCache.getFeedbyIds(feedIds);
		List<Feed> feeds = new ArrayList<Feed>();
		Feed cachedFeed = null;
		for (String feedId: feedIds){
			GetsResponse<Feed> res = cacheFeedsRes.get(feedId);
			if(res!=null){
				cachedFeed = cacheFeedsRes.get(feedId).getValue();
			}
			if(cachedFeed==null){
				cachedFeed = feedDao.getFeedById(feedId);
			}
			feeds.add(cachedFeed);
		}
		return feeds;
	}

	public void makeFeedSearchIndex(Feed feed) {
		//TODO:
		
	}
	
	public void pushFeedCommentRelation(Feed commentFeed){
		frCache.pushFeedCommentRelation(commentFeed);
	}

	public List<Feed> listComments(String feedId) {
		List<String>  commentIds  = frCache.listCommentIds(feedId);
		return getFeedbyIds(commentIds);
	}
	
	public void incrCommentsCount(String feedId){
		frCache.incrCommentsCount(feedId);
	}
	
	public void decrCommentsCount(String feedId){
		frCache.decrCommentsCount(feedId);
	}
	
	public int getCommentsCount(String feedId){
		return frCache.getCommentsCount(feedId);
		
	}
	
	public void favorFeed(String feedId, String userId) {
		frCache.favorFeed(feedId, userId);
	}

	public void unFavorFeed(String feedId, String userId) {
		frCache.unFavorFeed(feedId, userId);
		
	}

	public List<Feed> getFavorFeeds(String userId) {
		List<String> feedIds = frCache.getFavorFeedIds(userId);
		
		return getFeedbyIds(feedIds);
	}


	public void incrUserFeedCount(String userId){
		frCache.incrUserFeedCount(userId);
	}
	

	public void decrUserFeedCount(String userId){
		frCache.decrUserFeedCount(userId);
	}
	
	public int getUserFeedCount(String userId) {
		
		return frCache.getUserFeedCount(userId);
	}

	public void deleteFeed(String feedId) {
		// TODO Auto-generated method stub
		//feedCache.
		
	}

}
